package gerenciaDados.cln.cgt.PI.preProcessamento;
import java.awt.Color;
import java.awt.image.BufferedImage;

public class Filtro {
	
	private static void shellSort(Integer[] nums) {
		int n = nums.length;
	    int h = n / 2;
	    int c, j;
	    while (h > 0) {
	            for (int i = h; i < n; i++) {
	                    c = nums[i];
	                    j = i;
	                    while (j >= h && nums[j - h] > c) {
	                            nums[j] = nums[j - h];
	                            j = j - h;
	                    }
	                    nums[j] = c;
	            }
	            h = h / 2;
	    }
	}
	
	public static BufferedImage mediana(BufferedImage img){
		BufferedImage imagemfiltrada;
		int index;
		int largura = img.getWidth();
		int altura = img.getHeight();
		Color c, v;
		int [] pixels = img.getRGB(0, 0, largura, altura, null, 0, largura);		
		int [] rgbmedio = new int[largura*altura];
		
		Integer [] Rmascara = new Integer[9];
		Integer [] Gmascara = new Integer[9];
		Integer [] Bmascara = new Integer[9];

		for (int col = 0; col < largura; col++) {
			for (int lin = 0; lin < altura; lin++) {
				index = largura * lin + col;
				c = new Color(pixels[index]);					    			   							
				Rmascara[0] = c.getRed();							
				Gmascara[0] = c.getGreen();
				Bmascara[0] = c.getBlue();

				//esquerda  
				if(index % largura != 0){ 
					v = new Color(pixels[index-1]);
					Rmascara[1] = v.getRed();							
					Gmascara[1] = v.getGreen();
					Bmascara[1] = v.getBlue();
				}else{
					Rmascara[1] = 0;							
					Gmascara[1] = 0;
					Bmascara[1] = 0;
				}
				//direita
				if((index+1) % largura != 0){ 						
					v = new Color(pixels[index+1]);
					Rmascara[2] = v.getRed();							
					Gmascara[2] = v.getGreen();
					Bmascara[2] = v.getBlue();
				}else{
					Rmascara[2] = 0;							
					Gmascara[2] = 0;
					Bmascara[2] = 0;
				}

				//topo
				if(index > largura){ 
					v = new Color(pixels[index-largura]);
					Rmascara[3] = v.getRed();							
					Gmascara[3] = v.getGreen();
					Bmascara[3] = v.getBlue();
				}else{
					Rmascara[3] = 0;							
					Gmascara[3] = 0;
					Bmascara[3] = 0;
				}
				
				//base
				if(index < largura*altura - largura){ 
					v = new Color(pixels[index+largura]);
					Rmascara[4] = v.getRed();							
					Gmascara[4] = v.getGreen();
					Bmascara[4] = v.getBlue();
				}else{
					Rmascara[4] = 0;							
					Gmascara[4] = 0;
					Bmascara[4] = 0;
				}
				
				//esquerda-topo
				if(index % largura != 0 && index > largura){ 
					v = new Color(pixels[index-largura-1]);
					Rmascara[5] = v.getRed();							
					Gmascara[5] = v.getGreen();
					Bmascara[5] = v.getBlue();
				}else{
					Rmascara[5] = 0;							
					Gmascara[5] = 0;
					Bmascara[5] = 0;
				}
				
				//esquerda-base
				if(index % largura != 0 && index < largura*altura - largura){ 
					v = new Color(pixels[index+largura-1]);
					Rmascara[6] = v.getRed();							
					Gmascara[6] = v.getGreen();
					Bmascara[6] = v.getBlue();
				}else{
					Rmascara[6] = 0;							
					Gmascara[6] = 0;
					Bmascara[6] = 0;
				}
				
				//direta-topo
				if((index+1) % largura != 0 && index > largura){ 
					v = new Color(pixels[index-largura+1]);
					Rmascara[7] = v.getRed();							
					Gmascara[7] = v.getGreen();
					Bmascara[7] = v.getBlue();
				}else{
					Rmascara[7] = 0;							
					Gmascara[7] = 0;
					Bmascara[7] = 0;
				}
				
				//direita-base
				if((index+1) % largura != 0 && index < largura*altura - largura){ 
					v = new Color(pixels[index+largura+1]);
					Rmascara[8] = v.getRed();							
					Gmascara[8] = v.getGreen();
					Bmascara[8] = v.getBlue();
				}else{
					Rmascara[8] = 0;							
					Gmascara[8] = 0;
					Bmascara[8] = 0;
				}
				
				Filtro.shellSort(Rmascara);
				Filtro.shellSort(Gmascara);
				Filtro.shellSort(Bmascara);
				rgbmedio[index] = new Color(Rmascara[3],Gmascara[3],Bmascara[3]).getRGB();								 			
			}
		}
		imagemfiltrada = new BufferedImage(largura, altura, img.getType());
		imagemfiltrada.setRGB(0, 0, largura, altura, rgbmedio, 0, largura);
		return imagemfiltrada;
		
	}	
	
	public static BufferedImage mediana2(BufferedImage img){
		BufferedImage imagemfiltrada;
		int mask=7;
		int d = (mask-1)/2;
		int index = 0;
		int largura = img.getWidth();
		int altura = img.getHeight();
		Color c;
		int [] pixels = img.getRGB(0, 0, largura, altura, null, 0, largura);
		
		int [] moldura = new int[pixels.length + 2*d*largura + 2*d*altura + 4];
		int [] rgbmedio = new int[largura*altura];		
				
		int l;
		Integer [] Rmascara = new Integer[mask*mask];
		Integer [] Gmascara = new Integer[mask*mask];
		Integer [] Bmascara = new Integer[mask*mask];
		
		for(int y=0; y<altura;y++){
			for(int x=0; x<largura;x++){
				moldura[(y+d)*(largura+(2*d)) + (x+d)] = pixels[y*largura + x];
			}
		}

		for(int y=d; y<altura+d;y++){
			for(int x=d; x<largura+d;x++){
				l=0;
				for(int iy=y-d; iy <= y+d; iy++){
					for(int ix=x-d; ix <= x+d; ix++){
						c = new Color(moldura[iy*(largura+(2*d)) + ix]);
						Rmascara[l] = c.getRed();
						Gmascara[l] = c.getGreen();
						Bmascara[l] = c.getBlue();
						l++;
					}
				}
				Filtro.shellSort(Rmascara);
				Filtro.shellSort(Gmascara);
				Filtro.shellSort(Bmascara);
				rgbmedio[index++] = new Color(Rmascara[(mask*mask-1)/2],Gmascara[(mask*mask-1)/2],Bmascara[(mask*mask-1)/2]).getRGB();						
			}
		}
						
		imagemfiltrada = new BufferedImage(largura, altura, img.getType());
		imagemfiltrada.setRGB(0, 0, largura, altura, rgbmedio, 0, largura);
		return imagemfiltrada;
		
	}
}
